import { BufferAttribute, Float32BufferAttribute } from "../../thirdparty/three/imports";
import { Usage, usageNames, usageValues } from "../../thirdparty/three/polyfills/constants/Usage";

export class BufferAttribute3D
{
    get _bufferAttribute()
    {
        return this.__bufferAttribute;
    }
    set _bufferAttribute(v)
    {
        BufferAttribute3D._map.delete(this.__bufferAttribute);
        this.__bufferAttribute = v;
        BufferAttribute3D._map.set(this.__bufferAttribute, this);
    }
    protected __bufferAttribute: BufferAttribute;

    setXYZ(index: number, x: number, y: number, z: number)
    {
        this._bufferAttribute.setXYZ(index, x, y, z);

        return this;
    }

    setX(index: number, x: number)
    {
        this._bufferAttribute.setX(index, x);

        return this;
    }

    getY(index: number)
    {
        return this._bufferAttribute.getY(index);
    }

    setY(index: number, x: number)
    {
        this._bufferAttribute.setY(index, x);

        return this;
    }

    setZ(index: number, x: number)
    {
        this._bufferAttribute.setZ(index, x);

        return this;
    }

    get count()
    {
        return this._bufferAttribute.count;
    }

    // eslint-disable-next-line accessor-pairs
    set needsUpdate(v: boolean)
    {
        this._bufferAttribute.needsUpdate = v;
    }

    get array()
    {
        return this._bufferAttribute.array as number[];
    }

    constructor(array?: ArrayLike<number>, itemSize?: number, normalized?: boolean)
    {
        this._bufferAttribute = new BufferAttribute(array, itemSize, normalized);
    }

    get usage()
    {
        return usageNames[this._bufferAttribute.usage];
    }
    set usage(v)
    {
        this._bufferAttribute.usage = usageValues[v];
    }

    setUsage(usage: Usage)
    {
        this._bufferAttribute.setUsage(usageValues[usage]);

        return this;
    }

    static get(bufferAttribute: BufferAttribute)
    {
        let bufferAttribute3d = this._map.get(bufferAttribute);
        if (!bufferAttribute3d)
        {
            bufferAttribute3d = new BufferAttribute3D();
            bufferAttribute3d._bufferAttribute = bufferAttribute;
        }

        return bufferAttribute3d;
    }
    protected static _map = new Map<BufferAttribute, BufferAttribute3D>();
}

export class Float32BufferAttribute3D extends BufferAttribute3D
{
    constructor(array: number | Iterable<number> | ArrayLike<number> | ArrayBuffer, itemSize: number, normalized?: boolean)
    {
        super();
        this._bufferAttribute = new Float32BufferAttribute(array, itemSize, normalized);
    }
}
